package com.apes.fn.server.workOrder.service.MaintenanceOrderProcess;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.scm.commodityInquiry.model.ExternalInquiryItem;
import com.apes.fn.scm.commodityInquiry.repository.ExternalInquiryItemRepository;
import com.apes.fn.scm.commodityInquiry.repository.ExternalInquiryRepository;
import com.apes.fn.server.servicePlan.model.GetPriceLogger;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.model.ServicePlanItem;
import com.apes.fn.server.servicePlan.repository.GetPriceLoggerRepository;
import com.apes.fn.server.servicePlan.repository.ServicePlanDao;
import com.apes.fn.server.servicePlan.repository.ServicePlanItemRepository;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.fn.server.servicePlan.service.ConditionBuilder;
import com.apes.fn.server.servicePlan.service.ServicePlanceService;
import com.apes.fn.server.servicePlan.service.ServiceToForeign;
import com.apes.fn.server.workOrder.model.MaintenanceOrder;
import com.apes.fn.server.workOrder.repository.MaintenanceOrderDao;
import com.apes.fn.server.workOrder.repository.MaintenanceOrderRepository;
import com.apes.fn.server.workOrder.service.ConstructionRecordService;
import com.apes.fn.server.workOrder.service.MaintenanceOrderService;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.logger.ApesLoggerRepository;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.soe.store.database.repository.BusinessAttributeValueRepository;
import com.apes.framework.util.Arith;
import com.apes.framework.util.LogicalUtil;
import com.apes.framework.util.MapUtil;
import com.apes.framework.util.Tools;
import com.apes.pi.service.PiManager;
import com.apes.scm.contract.model.Contract;
import com.apes.scm.contract.repository.ContractRepository;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.model.Channel;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.repository.StoreRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.CorporateRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: apes-server
 * @description: 服务工单-外协流程
 * @author: czs
 * @create: 2023-05-22 11:40
 **/
@Service("maintenanceOrderOutWorkService")
public class MaintenanceOrderOutWorkService extends DomainService {

    @Autowired
    private MaintenanceOrderService maintenanceOrderService;
    @Autowired
    private MaintenanceOrderRepository maintenanceOrderRepository;
    @Autowired
    private ServicePlanRepository servicePlanRepository;
    @Autowired
    private ServicePlanItemRepository servicePlanItemRepository;
    @Autowired
    private ServicePlanceService servicePlanceService;
    @Autowired
    private ServiceToForeign serviceToForeign;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private BusinessAttributeValueRepository businessAttributeValueRepository;
    @Autowired
    private MaintenanceOrderDao maintenanceOrderDao;
    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private StoreRepository storeRepository;
    @Autowired
    private GetPriceLoggerRepository getPriceLoggerRepository;

    /**
     * 转外协
     * 主要处理逻辑
     * @param maintenanceOrders
     * @param person
     * @return
     */
    public ServicePlan toOutProcess(List<MaintenanceOrder> maintenanceOrders, PartyRole person) {
        //写入协助类型和操作员
        maintenanceOrderChangeAssistType(maintenanceOrders);
        //验证选中商品是否能选并获取选中商品
        List<MaintenanceOrder> resultLists = checkToOutCondition(maintenanceOrders);
        //更改转外协工单所有状态
        changeMaintenanceOrderToOut(person, resultLists);
        //获取外协价格
        findOutPrice(maintenanceOrders);
        //改变方案状态
        ServicePlan servicePlan = outChangeServicePlan(resultLists,true);
        //更新平台字段并保存
        resultLists = maintenanceOrderService.updateMaintenanceOrders(resultLists);
        //平台外自动转派工
        List<MaintenanceOrder> outPlatform = resultLists.stream()
                .filter(maintenanceOrder ->
                                maintenanceOrder.getOutAssistType().equals("outPlatform")&&
                                        (maintenanceOrder.getServicePlanItem().getOldInquiryNumber()==null
                                                ||
                                                !maintenanceOrder.getServicePlanItem().getOldInquiryNumber().startsWith("WC")
                                        )
                        )
                .map(maintenanceOrder -> {
                    MaintenanceOrder one = maintenanceOrderRepository.findOne(maintenanceOrder.getId());
                    one.setSelected(true);
                    return one;
                })
                .collect(Collectors.toList());

        if (outPlatform.isEmpty())return servicePlan;
        PartyRole partyRole = SpringManager.getBean(PartyRoleRepository.class).findOne("00002256");
        dispatchProcess(outPlatform,partyRole);
        //日志标记
        servicePlan.setAutoDispatchProcess(!outPlatform.isEmpty());
        return servicePlan;
    }


    /**
     * 派工主要处理逻辑
     * @param maintenanceOrders
     * @param person
     */
    public void dispatchProcess(List<MaintenanceOrder> maintenanceOrders, PartyRole person) {
        //判断是否能进行退回，改变当前工单的状态
        List<MaintenanceOrder> resultLists = maintenanceOrders.stream().filter((maintenanceOrder)->{
            checkValidContract(maintenanceOrder.getContract());
            return maintenanceOrder.isSelected() && "waitDispatch".equals(maintenanceOrder.getDispatcheState());
        }).collect(Collectors.toList());
        if(resultLists.size() == 0) throw new RuntimeException("请选择有效合适的转外协商品");

//        //重取成本
        JSONArray priceArray = serviceToForeign.getGS52(resultLists.stream().map((maintenanceOrder) -> {
            return MapUtil.mapper(
                    "uniqueIdentify", maintenanceOrder.getId(),
                    "PLID", maintenanceOrder.getProduct().getClassify().getId(),
                    "P001", maintenanceOrder.getPlatformPriceCosInTaxTemp(),
                    "PPID",maintenanceOrder.getProduct().getBrand().getId(),
                    "YYMS", maintenanceOrder.getBelongDept().getCompany().getParty().getCorporate().getOperation().getCode(),
                    "NYYMS", maintenanceOrder.getBelongDept().getCompany().getParty().getCorporate().getOperation().getId(),
                    "XSDJ", 0,
                    "SYGSID", maintenanceOrder.getPlatform().getId(),
                    "GSID", maintenanceOrder.getBelongDept().getCompany().getId(),
                    "SPID", maintenanceOrder.getProduct().getId()
//                    "GYSID", maintenanceOrder.getSupplier().getId()

            );
        }).collect(Collectors.toList()));

        //更改转外协工单所有状态
        resultLists.stream().forEach(maintenanceOrder -> {
            boolean flag = true;
            for (int i = 0; i < priceArray.size(); i++) {
                JSONObject item = priceArray.getJSONObject(i);
                if (maintenanceOrder.getId().equals(item.getString("uniqueIdentify"))) {
//                    dispatchOrder.setPlatformPriceCosInTax(); //平台成本，不用重取
                    if(item.getDouble("priceCostUnitInTax") <= 0) throw new RuntimeException("取成本有误");
                    maintenanceOrder.setPriceCostUnitInTaxTemp(item.getDouble("priceCostUnitInTax")); //
                    flag = false;
                }
            }
            if(flag)  throw new RuntimeException("外协派工，重取成本有误");

            //设置一些原工单信息
            maintenanceOrder.setDispatcheState("dispatch");
            maintenanceOrder.setDispatchDate(new Date());
            maintenanceOrder.setDispatchUid(person);

            //改变外协类型
            maintenanceOrder.transferOutAssist();
        });
        resultLists = maintenanceOrderService.updateMaintenanceOrders(resultLists);
        changePlanPlatByMaintenOrder(resultLists);
        //生成外协工单
        List<MaintenanceOrder> outMaintenanceOrders = createOutMaintenanceOrderByMaintenanceOrder(resultLists);
        //回写方案派工日志
//        ServicePlan servicePlan = maintenanceOrders.stream().findAny().get().getServicePlanItem().getServicePlan();

    }

    private void checkValidContract(Contract contract) {
        if (contract.getState().equals("approve")) {
            if (contract.getValidFrom().after(new Date())){
                throw new RuntimeException(appendContractIdAndName(contract)+"未到起始有效期");
            }else if(contract.getValidPeriod().before(new Date())){
                throw new RuntimeException(appendContractIdAndName(contract)+"已超出有效期");
            }
        }else if (contract.getState().equals("repeal")){
            throw new RuntimeException(appendContractIdAndName(contract)+"已终止");
        }else if (contract.getState().equals("extension")){
            throw new RuntimeException(appendContractIdAndName(contract)+"延期中,请审核");
        }
    }

    private String appendContractIdAndName(Contract contract) {
        return "合同:[" +contract.getId()+"]"+ contract.getName() + " ";
    }


    /**
     * 派工界面编辑
     * @param maintenanceOrders
     * @return
     */
    public Map dispachOrderUpdateProecss(List<MaintenanceOrder> maintenanceOrders){

        //判断是否能进行退回，改变当前工单的状态
        List<MaintenanceOrder> resultLists = maintenanceOrders.stream().filter((maintenanceOrder)->{
            return maintenanceOrder.isSelected() && "waitDispatch".equals(maintenanceOrder.getDispatcheState());
        }).collect(Collectors.toList());
        if(resultLists.size() == 0) throw new RuntimeException("请选择有效合适的转外协商品");

        resultLists.stream().forEach(maintenanceOrder -> {
            maintenanceOrder.transferOutAssist();
        });

        //更改转外协工单所有状态
//        resultLists.stream().forEach(maintenanceOrder -> {
//            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_CREATE);
//            maintenanceOrder.setDispatcheState("back");
//            maintenanceOrder.setDispatchBackDate(new Date());
//            maintenanceOrder.setDispatchBackUid(getPerson(simpleRequest));
//
//        });
        resultLists = maintenanceOrderService.updateMaintenanceOrders(resultLists);

        changePlanPlatByMaintenOrder(resultLists);
        return this.invoke("fn.maintenance.findDispachOrder",MapUtil.mapper("SERVICE_PLAN_ID",maintenanceOrders.stream().findFirst().get().getServicePlanItem().queryServicePlanByItem().getId(),"STATE","waitDispatch"));
    }
    /**
     * 外协重新派工主要逻辑
     * @param maintenanceOrders
     * @param person
     * @return
     */
    public ServicePlanItem reDispatchProcess(List<MaintenanceOrder> maintenanceOrders, PartyRole person) {
        List<MaintenanceOrder> outPlatform = new ArrayList<>();
        maintenanceOrders.forEach(maintenanceOrder -> {
            maintenanceOrder.setSelected(true);
            //设置当前单据信息
            maintenanceOrder.setState("back");
            maintenanceOrder.setOutBackDate(new Date());
            maintenanceOrder.setOutBackUid(person);
            maintenanceOrder = maintenanceOrderService.save(maintenanceOrder);

            //设置来源单据信息
            MaintenanceOrder originOrder = maintenanceOrderRepository.findOne(maintenanceOrder.getSourceFrom());
            if(originOrder == null) throw new RuntimeException("来源单据出现错误，请检查");

            originOrder.setDispatcheState("waitDispatch");
            originOrder.setDispatchDate(null);
            originOrder.setDispatchBackUid(null);
            originOrder = maintenanceOrderService.save(originOrder);
            if (originOrder.getOutAssistType().equals("outPlatform")){
                originOrder.setSelected(true);
                outPlatform.add(originOrder);
            }
        });
        ServicePlanItem servicePlanItem = maintenanceOrders.stream().findFirst().get().getServicePlanItem();
        ServicePlan servicePlan = servicePlanItem.getServicePlan();
        maintenanceOrders.forEach(maintenanceOrder -> maintenanceOrderService.servicePlanItemWorkState(maintenanceOrder,servicePlan,"waitDispatch",false));
        servicePlanceService.updateOnly(servicePlan);
        User user =userRepository.findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);
        servicePlanceService.addServicePlanLogger(servicePlan,"外协工单重新派工","",user);
        if (!outPlatform.isEmpty()){
            dispatchBackProcess(outPlatform,person);
            servicePlanceService.addServicePlanLogger(servicePlan,"外协派工退回","",user);
        }
        return servicePlanItem;
    }


    /**
     * 外协派工单 派工退回操作
     * @param maintenanceOrders
     * @param person
     * @return
     */
    public ServicePlan dispatchBackProcess(List<MaintenanceOrder> maintenanceOrders, PartyRole person) {
        //判断是否能进行退回，改变当前工单的状态
        List<MaintenanceOrder> resultLists = maintenanceOrders.stream().filter((maintenanceOrder)->{
            return maintenanceOrder.isSelected() && "waitDispatch".equals(maintenanceOrder.getDispatcheState());
        }).collect(Collectors.toList());
        if(resultLists.size() == 0) throw new RuntimeException("请选择有效合适的转外协商品");
        //更改转外协工单所有状态
        resultLists.stream().forEach(maintenanceOrder -> {
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_CREATE);
            maintenanceOrder.setDispatcheState("back");
            maintenanceOrder.setDispatchBackDate(new Date());
            maintenanceOrder.setDispatchBackUid(person);
            maintenanceOrder.setToOutUid(null);
            maintenanceOrder.setToOutDate(null);
            maintenanceOrder.setContract(null);
        });
        resultLists = maintenanceOrderService.updateMaintenanceOrders(resultLists);
        outChangeServicePlan(maintenanceOrders,false);
        ServicePlan servicePlan = maintenanceOrders.stream().findAny().get().getServicePlanItem().getServicePlan();
        maintenanceOrders.forEach(maintenanceOrder -> maintenanceOrderService.servicePlanItemWorkState(maintenanceOrder,servicePlan,"back",false));
        servicePlanceService.updateOnly(servicePlan);
        return maintenanceOrders.stream().findAny().get().getServicePlanItem().getServicePlan();
    }


    /**
     * 转外协,更改方案上的类型：转和退回
     * @param maintenanceOrders
     * @return
     */
    public ServicePlan outChangeServicePlan(List<MaintenanceOrder> maintenanceOrders,boolean flag){
        ServicePlan servicePlan = servicePlanRepository.findOne(maintenanceOrders.stream().findFirst().get().getServicePlanId());
        if(servicePlan == null) throw new RuntimeException("单据有误，根据明细找不到对应方案");
        servicePlan.getServicePlanItems().forEach(servicePlanItem -> {
            maintenanceOrders.forEach(maintenanceOrder -> {
                if(maintenanceOrder.isSelected() && maintenanceOrder.getServicePlanItem().getId().equals(servicePlanItem.getId())){
                    maintenanceOrderService.servicePlanItemWorkState(maintenanceOrder,servicePlan,"waitDispatch",false);
                    if(flag){
                        servicePlanItem.setAssistType(businessAttributeValueRepository.findOne("ServicePlanItem.assistType.outer"));
                    }else{
                        servicePlanItem.setAssistType(businessAttributeValueRepository.findOne("ServicePlanItem.assistType.normal"));
                    }
                }
            });
        });
        return servicePlanceService.updateOnly(servicePlan);
    }



    /**
     * 派工：从工单生层另一张工单
     * @param resultLists
     * @return
     */
    public List<MaintenanceOrder> createOutMaintenanceOrderByMaintenanceOrder(List<MaintenanceOrder> resultLists) {
        List<MaintenanceOrder> outMaintenanceOrders = resultLists.stream().map(maintenanceOrder -> {
            MaintenanceOrder maintenanceOrder1 = MapUtil.getO(maintenanceOrder,MaintenanceOrder.class);
            maintenanceOrder1.setId(null);
            maintenanceOrder1.setBusinessType(MaintenanceOrder.WORK_ORDER_OUT);
            maintenanceOrder1.setBusinessTypeName("外协工单");
            maintenanceOrder1.setState(MaintenanceOrder.CONST_TABLE_STATE_CREATE);
            maintenanceOrder1.setWorkState(MaintenanceOrder.WORK_ORDER_WORKSTATE_WAIT);
            maintenanceOrder1.setDispatcheState("none");

            maintenanceOrder1.setDispatchUid(null);
            maintenanceOrder1.setDispatchDate(null);
            maintenanceOrder1.setDispatchBackUid(null);
            maintenanceOrder1.setDispatchBackDate(null);
            maintenanceOrder1.setToOutDate(null);
            maintenanceOrder1.setToOutUid(null);

            maintenanceOrder1.setPlatformPurchaseCost(maintenanceOrder.getPlatformPurchaseCost());
            maintenanceOrder1.setPlatformPriceCosInTax(maintenanceOrder1.getPlatformPriceCosInTaxTemp());
            maintenanceOrder1.setPriceCostUnitInTax(maintenanceOrder1.getPriceCostUnitInTaxTemp());

            maintenanceOrder1.setSourceFrom(maintenanceOrder.getId());
            maintenanceOrder1.setSourceType("maintenanceOrder");
            return maintenanceOrder1;
        }).collect(Collectors.toList());

        return maintenanceOrderService.updateMaintenanceOrders(outMaintenanceOrders);
    }

    /**
     * 写入协助类型
     * @param maintenanceOrders
     */
    private void maintenanceOrderChangeAssistType(List<MaintenanceOrder> maintenanceOrders) {
        maintenanceOrders.forEach(maintenanceOrder -> {
            //前端设置的转外协，限定了只有两种值，导致一些不需要的也选择了，先修改那部分数据（前端优化显示）
            if(!maintenanceOrder.isSelected() && MaintenanceOrder.CONST_TABLE_STATE_CREATE.equals(maintenanceOrder.getState())){
                maintenanceOrder.setAssistType("notOut");
            }else if (maintenanceOrder.isSelected()){//服务方案入口进入的没有设置转外协标记
                maintenanceOrder.setAssistType("toOut");
                Store store = storeRepository.findByDept(maintenanceOrder.getBelongDept());
                maintenanceOrder.setContainSpace(store.isContainSpace());
            }
        });
    }

    /**
     * 根据工单回填方案的平台
     * 派工界面修改，和派工操作有这个操作
     * @param
     * @return
     */
    public void changePlanPlatByMaintenOrder(List<MaintenanceOrder> maintenanceOrders){
        ServicePlan servicePlan = maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan();
        servicePlan.getServicePlanItems().forEach(servicePlanItem -> {
            MaintenanceOrder maintenanceOrderR = maintenanceOrders.stream().filter(maintenanceOrder ->{return maintenanceOrder.getServicePlanItem().getId().equals(servicePlanItem.getId());}).findFirst().orElse(null);
            if(maintenanceOrderR != null){
                servicePlanItem.setPlatform(maintenanceOrderR.getPlatform());
                maintenanceOrderService.servicePlanItemWorkState(maintenanceOrderR,servicePlan,"dispatch",false);
            }
        });
        servicePlanceService.updateOnly(servicePlan);
    }

    /**
     * 验证选中商品是否能选并且获取选中商品(转外协)
     * @param maintenanceOrders
     * @return
     */
    private List<MaintenanceOrder> checkToOutCondition(List<MaintenanceOrder> maintenanceOrders) {
        List<MaintenanceOrder> resultLists = maintenanceOrders.stream().filter((maintenanceOrder)->{
            return maintenanceOrder.isSelected() && maintenanceOrder.checkCanInnerOrOut();
        }).collect(Collectors.toList());
        if(resultLists.size() == 0) throw new RuntimeException("请选择有效合适的转外协商品");
        resultLists.stream().filter(maintenanceOrder -> maintenanceOrder.getOutAssistType().equals("outPlatform")).forEach(this::checkToOutRequiredColumns);
        return resultLists;
    }
    private void checkToOutRequiredColumns(MaintenanceOrder maintenanceOrder){
        boolean err = false;
        StringBuffer sf =new StringBuffer();
        sf.append("平台外商品:"+maintenanceOrder.getProduct().getName()+",缺少必填字段:");
        if (maintenanceOrder.getPlatformPriceCosInTaxTemp()==0) {
            err=true;
            sf.append("成本单价 ");
        }
        if (maintenanceOrder.getInquiryReasonType()==null){
            err=true;
            sf.append("平台外协助原因 ");
        }
        if (maintenanceOrder.getDeptRemark()==null||"".equals(maintenanceOrder.getDeptRemark().replace(" ",""))){
            err=true;
            sf.append("门店备注 ");
        }
        if (maintenanceOrder.getSettlementType()==null) {
            err=true;
            sf.append("结算方式 ");
        }
        if (err)throw new RuntimeException(sf.toString());
    }

    private Object checkToOut(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        List<MaintenanceOrder> maintenanceOrders =  maintenanceOrderService.maintenanceOrdersTransfer(jo.getJSONArray("maintenanceOrders"));
        checkToOutCondition(maintenanceOrders);
        return jo;
    }



    /**
     * 改变工单明细状态至外协
     * @param person
     * @param resultLists
     */
    private void changeMaintenanceOrderToOut(PartyRole person, List<MaintenanceOrder> resultLists) {
        resultLists.forEach(maintenanceOrder -> {
            maintenanceOrder.setState(MaintenanceOrder.CONST_TABLE_STATE_OUTER);
            maintenanceOrder.setDispatcheState("waitDispatch");
            maintenanceOrder.setToOutDate(new Date());
            maintenanceOrder.setToOutUid(person);
//            Channel channel = maintenanceOrder.getServicePlanItem().getServicePlan().getChannel();

            maintenanceOrder.setLockState(false); //ESB-5799
            maintenanceOrder.transferOutAssistConfirm(); //转化

            if("outPlatform".equals(maintenanceOrder.getOutAssistType())){
                Enumeration operation = maintenanceOrder.getBelongDept().getCompany().getParty().getCorporate().getOperation();
                Contract contract =null;
                if ("001073".equals(operation.getId())){
                    List<Contract> contracts= SpringManager.getBean(ContractRepository.class).findAll(JpaDsl.toCriteria(
                            "validPeriod","GTE",   new Date(),
                            "validFrom","LTE",   new Date(),
                            "repealDate","EQ",   null,
                            "approveDate","NE",   null,
                            "consignInstall" , "EQ" , true,
                            "contractType.code","EQ","platform",
                            "partner.id","EQ","004465",
                            "settlementType.code","EQ","deptCash"));
                    if(contracts.size() == 0) throw new RuntimeException("存在现金外采商品，需自动外协，没有找到对应合同，请检查");
                    contract = contracts.stream().findFirst().get();
                }else {
                    List<Contract> contracts= SpringManager.getBean(ContractRepository.class).findAll(JpaDsl.toCriteria(
                            "validPeriod","GTE",   new Date(),
                            "validFrom","LTE",   new Date(),
                            "repealDate","EQ",   null,
                            "approveDate","NE",   null,
                            "consignInstall" , "EQ" , true,
                            "contractType.code","EQ","supplier",
                            "partner.id","EQ","004141",
                            "settlementType.code","EQ","totalCash"));
                    if(contracts.size() == 0) throw new RuntimeException("存在平台外商品，需自动外协，没有找到对应采购合同，请检查,合作伙伴编码[004141]");
                    contract = contracts.stream().findFirst().get();
                }

                maintenanceOrder.setContract(contract);
            }
        });
    }


    /**
     * 每个工单查询价格
     * @param maintenanceOrder
     * @param planMap 方案实体转Map
     */
    private void findOutPrice(MaintenanceOrder maintenanceOrder, Map planMap){
        ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
        ServicePlan servicePlan = servicePlanItem.getServicePlan();
        Product product = servicePlanItem.getProduct();
        GetPriceLogger priceLogger = servicePlanItem.getPriceSource()!=null?
                getPriceLoggerRepository.findOne(servicePlanItem.getPriceSource()) : null;
        double p101 = 0;
        double materialsCost = 0;
        double workFee = 0;
        double siteFee = 0;
        double platFee = 0;
        //首先判断是否询价商品
        if (servicePlanItem.getUniqueValue()!=null){
            mainGetContract(maintenanceOrder, servicePlanItem, planMap);
            if (maintenanceOrder.getSupplier()!=null){
                JSONObject resultJson = getCostInTaxAndXJ51(maintenanceOrder.getSupplier().getId(), servicePlanItem, servicePlan);
                if (maintenanceOrder.getPlatform().getId().equals("1001"))p101 = resultJson.getDoubleValue("P101");
                maintenanceOrder.setTaxRate(p101);
                maintenanceOrder.setPlatformPriceCosInTaxTemp(resultJson.getDoubleValue("P001"));
                maintenanceOrder.setPlatformPriceCosExTax(resultJson.getDoubleValue("S901"));
            }
        }
        //获取采购价格时先去查询取价日志,没有再查询新的价格
        if(maintenanceOrder.getSupplier()==null){
            JSONObject resultJson = new JSONObject();
            if (priceLogger!=null){
                resultJson = JSONObject.parseObject(priceLogger.getConditionResult());
            }else {
                ConditionBuilder xs51 = new ConditionBuilder.Builder("XS51")
                        .setDept(servicePlan.getBelongDept())
                        .product(product)
                        .fnCustomer(servicePlan.getCustomerCar())
                        .setPlatform(servicePlanItem.getPlatform())
                        .setSupplierId(maintenanceOrder.getSupplier())
                        .setProductUomId(servicePlanItem.getUom().getId())
                        .setCooperationType(servicePlan.getCooperationType())
                        .setUsableQty(0.0D).build().execConditionStrategy();
                resultJson = xs51.getResultJson();
            }

            String supplier_id = resultJson.getString("SUPPLIER_ID");
            maintenanceOrder.setPlatformPriceCosExTax(resultJson.getDoubleValue("P001"));
            getContract(maintenanceOrder, planMap, supplier_id);
            if (maintenanceOrder.getPlatform().getId().equals("1001"))p101 = resultJson.getDoubleValue("P101")/100;
            maintenanceOrder.setPlatformPriceCosInTaxTemp(Arith.round(resultJson.getDoubleValue("P001")*(1+p101),2));
            maintenanceOrder.setTaxRate(p101);
        }
        checkPlatfromType(maintenanceOrder);
        //因为是需要供应商和票点 所以先找到询价或者价格文件的供应商再找空间策略
        if(maintenanceOrder.getSupplier()==null)return;
        JSONObject spacePlanPrice = querySpacePlanPrice(maintenanceOrder);
        if (!spacePlanPrice.isEmpty()&&spacePlanPrice.get("K005")!=null&&spacePlanPrice.getDoubleValue("K005")>0.0D){
            double totalPrice = spacePlanPrice.getDoubleValue("K005");
            maintenanceOrder.setPlatformPriceCosExTax(totalPrice);
            maintenanceOrder.setPlatformPriceCosInTaxTemp(Arith.round(totalPrice*(1+p101),2));
            materialsCost= spacePlanPrice.getDoubleValue("K001");
            workFee= spacePlanPrice.getDoubleValue("K002");
            siteFee= spacePlanPrice.getDoubleValue("K003");
            platFee= spacePlanPrice.getDoubleValue("K004");
        }
        maintenanceOrder.setTaxRate(p101);
        maintenanceOrder.setMaterialsCost(materialsCost);
        maintenanceOrder.setWorkFee(workFee);
        maintenanceOrder.setSiteFee(siteFee);
        maintenanceOrder.setPlatFee(platFee);
    }

    private void checkPlatfromType(MaintenanceOrder maintenanceOrder) {
        if (maintenanceOrder==null)return;
        if(maintenanceOrder.getSupplier()==null)return;
        if ("004465".equals(maintenanceOrder.getSupplier().getId())) {
            maintenanceOrder.setOutAssistType("outPlatform");
            maintenanceOrder.setOutAssistTypeConfirm(false);
        }
    }


    /**
     * 获取多个工单外协价格
     * @param maintenanceOrders
     */
    private void findOutPrice(List<MaintenanceOrder> maintenanceOrders){
        if (maintenanceOrders.isEmpty())return;
        ServicePlan servicePlan = maintenanceOrders.stream().findFirst().get().getServicePlanItem().getServicePlan();
        Map planMap = MapUtil.mapped(servicePlan);
        Channel channel = servicePlan.getChannel();
        if(channel != null && LogicalUtil.in(channel.getName(),ServicePlanceService.PLATFORM_OUT_ORDER.get(0)))return;
        maintenanceOrders.stream()
                .filter(maintenanceOrder -> !maintenanceOrder.getServicePlanItem().isNeedAutoTransitionAssistTypeForKN())
                .forEach(maintenanceOrder -> findOutPrice(maintenanceOrder, planMap));
    }


    /**
     * 询价来源的外协工单获取供应商合同
     * @param maintenanceOrder
     * @param servicePlanItem
     * @param planMap
     */
    private void mainGetContract(MaintenanceOrder maintenanceOrder, ServicePlanItem servicePlanItem, Map planMap) {
        String gysid = "";
        if (servicePlanItem.getSupplier() != null){
            gysid = servicePlanItem.getSupplier().getId();
        }else {
            JSONObject spxjd = (JSONObject) maintenanceOrderDao.querySpxjdByWYZ(new JSONObject(MapUtil.mapper("WYZ", servicePlanItem.getUniqueValue()))).stream().findAny().orElse(null);
            if (spxjd==null) return;
            String oldgysid = spxjd.getString("GYSID");
            int i = oldgysid.length() - 6;
            gysid = oldgysid.substring(i);
        }
        getContract(maintenanceOrder,planMap,gysid);
    }


    /**
     * 获取票点和询价信息
     * @param partnerId
     * @param servicePlanItem
     * @param servicePlan
     * @return
     */
    public JSONObject getCostInTaxAndXJ51(String partnerId, ServicePlanItem servicePlanItem, ServicePlan servicePlan) {
        JSONObject resultJson = new JSONObject();
        JSONObject inquiryPoolProduct = new JSONObject();
        Double CGDJ = 0.0;
        Double XSDJ = 0.0;
        Double XSXJ = 0.0;
        Double P101 = 0.0;//税率
        Double S901 = 0.0;//不含税单价
        if ("2".equals(servicePlanItem.getPriceForward())) {
            CGDJ = servicePlanItem.getPlatformPriceCosInTax();
            XSDJ = servicePlanItem.getPriceUnit();
            XSXJ = servicePlanItem.getFloorPrice();
            //取票点
            Product product = servicePlanItem.getProduct();
            ConditionBuilder t11 = new ConditionBuilder.Builder("T11")
                    .setBrandId(product.getBrand().getId())
                    .setClassifyId(product.getClassify().getId())
                    .setSupplierId(servicePlanItem.getSupplier().getId()).build().execCondition();
            JSONObject t11ResultJson = t11.getResultJson();
            P101 = t11ResultJson.getDoubleValue("P101");
            S901 = servicePlanItem.getPriceCostUnitExTax();
        } else {
            inquiryPoolProduct = "004465".equals(partnerId)?findExternalInquiryPrice(servicePlanItem): serviceToForeign.getInquiryPoolProduct(MapUtil.mapped(servicePlan, "servicePlanItems"),
                    v -> v.getString("SPID").equals(servicePlanItem.getProduct().getId()) && v.getString("GYSID").contains(partnerId) && (servicePlanItem.getUniqueValue() == null || v.getString("WYZ").equals(servicePlanItem.getUniqueValue()))
            );
            if (inquiryPoolProduct.isEmpty()) return resultJson;
            CGDJ = inquiryPoolProduct.getDoubleValue("CGDJ");
            XSDJ = inquiryPoolProduct.getDoubleValue("XSDJ");
            XSXJ = inquiryPoolProduct.getDoubleValue("XSXJ");
        }

        JSONObject xj51 =new ConditionBuilder.Builder("XJ51")
                .setDept(servicePlan.getBelongDept())
                .setPlatform(servicePlanItem.getPlatform())
                .fnCustomer(servicePlan.getCustomerCar())
                .product(servicePlanItem.getProduct())
                .setSupplierId(partnerId)
                .setProductUomId(servicePlanItem.getUom().getId())
                .setCooperationType(servicePlan.getCooperationType())
                .setXJ(CGDJ,XSDJ,XSXJ)
                .build().execConditionStrategy().getResultJson();
        if (xj51.containsKey("P001") && xj51.getDouble("P001") > 0) {
            if ("2".equals(servicePlanItem.getPriceForward())){
                resultJson.put("P101",P101);//税率
                resultJson.put("S901",S901);//不含税单价
                resultJson.put("P001",xj51.getDouble("P001"));//含税单价
            }else {
                JSONArray jsonArray = maintenanceOrderDao.queryTaxAndInTaxPrice(inquiryPoolProduct);
                if (jsonArray.isEmpty()) {
                    resultJson.put("P101", 0);//税率
                    resultJson.put("S901", xj51.getDouble("P001"));//不含税单价
                    resultJson.put("P001", xj51.getDouble("P001"));//含税单价
                    return resultJson;
                } else {
                    JSONObject jsonObject = jsonArray.getJSONObject(0);
                    resultJson.put("P101", jsonObject.getDoubleValue("GYSSSBL") / 100);//税率
                    resultJson.put("S901", jsonObject.getDoubleValue("WSCGCKJ"));//不含税单价
                    resultJson.put("P001", xj51.getDouble("P001"));//含税单价
                }
            }
        }
        return resultJson;
    }

    private JSONObject findExternalInquiryPrice(ServicePlanItem servicePlanItem) {
        String oldInquiryNumber = servicePlanItem.getOldInquiryNumber();
        ExternalInquiryItem externalInquiryItem = SpringManager.getBean(ExternalInquiryItemRepository.class).accordIdAndUniqueFind(oldInquiryNumber, servicePlanItem.getUniqueValue());
        Map mapper = MapUtil.mapper("CGDJ", externalInquiryItem.getPurchaseUnit(), "XSDJ", externalInquiryItem.getPriceUnit(), "XSXJ",externalInquiryItem.getPriceLimit());
        return new JSONObject(mapper);
    }

    /**
     * 传入供应商/商品明细
     * 取出工单票点/含税价/不含税价/材料成本/施工费/场地费/平台费
     *
     * 取价优先级:空间价格 -> 询价价格 -> 价格文件
     * @param re
     * @return
     */
    public Map findPlatformPriceCosInTax(SimpleRequest re){
        JSONObject jo = re.getJO();
        String partnerId = jo.getString("partnerId");
        String servicePlanItemId = jo.getString("servicePlanItemId");

        ServicePlanItem servicePlanItem = servicePlanItemRepository.findOne(servicePlanItemId);
        MaintenanceOrder order = maintenanceOrderRepository.findFirstByServicePlanItemAndBusinessTypeNotIn(servicePlanItem, Collections.singletonList("out"));
        PartyRole partner = partyRoleRepository.findOne(partnerId);

        ServicePlan servicePlan = servicePlanItem.getServicePlan();
        Product product = servicePlanItem.getProduct();

        //取票点
        ConditionBuilder t11 = new ConditionBuilder.Builder("T11")
                .setBrandId(product.getBrand().getId())
                .setClassifyId(product.getClassify().getId())
                .setSupplierId(partner.getId()).build().execCondition();
        JSONObject t11ResultJson = t11.getResultJson();

        Enumeration workType = order.getWorkType();
        if (workType==null) workType = enumerationRepository.findOne("001947");


        //取空间计划策略
        ConditionBuilder kjjh = new ConditionBuilder.Builder("CX_KJJH")
                .setSupplierId(partnerId)
                .setDept(order.getBelongDept())
                .product(product)
                .build()
                .execConditionStrategy()
                .formatAmount();
        JSONObject spacePlanPrice = kjjh.getResultJson();
        if (!spacePlanPrice.isEmpty() && spacePlanPrice.get("K005") != null && spacePlanPrice.getDoubleValue("K005") > 0.0D) {
            return platformPriceCosInTaxReturnTemp(spacePlanPrice.get("K005"), spacePlanPrice.getDoubleValue("K005") * (1 + (t11ResultJson.getDoubleValue("P101") / 100))
                    , t11ResultJson.get("P101"), spacePlanPrice.get("K001"), spacePlanPrice.get("K002"), spacePlanPrice.get("K003"), spacePlanPrice.get("K004"));
        }
        //取询价价格文件
        JSONObject resultJson = getCostInTaxAndXJ51(partnerId, servicePlanItem, servicePlan);

        if (resultJson.containsKey("P001") && (Double)resultJson.get("P001") > 0)
            return platformPriceCosInTaxReturnTemp(resultJson.get("S901"),resultJson.get("P001"),resultJson.get("P101"),0,0,0,0);


        //取采购价格文件
        Map xs51 = findPlatformPriceCosInTaxForXS51(partnerId, servicePlanItem, servicePlan, product, partner);
        if (!xs51.isEmpty())return xs51;

        //取不到价格就只返回票点
        if (t11ResultJson.getBigDecimal("P101")!=null){
            return platformPriceCosInTaxReturnTemp(0,0,t11ResultJson.getBigDecimal("P101"),0,0,0,0);
        }

        return platformPriceCosInTaxReturnTemp(0,0,0,0,0,0,0);
    }


    /**
     * 取采购价格文件
     * @param partnerId
     * @param servicePlanItem
     * @param servicePlan
     * @param product
     * @param partner
     * @return
     */
    private Map findPlatformPriceCosInTaxForXS51(String partnerId, ServicePlanItem servicePlanItem, ServicePlan servicePlan, Product product, PartyRole partner) {
        JSONObject resultJson;
        ConditionBuilder xs51 = new ConditionBuilder.Builder("XS51")
                .setDept(servicePlan.getBelongDept())
                .product(product)
                .fnCustomer(servicePlan.getCustomerCar())
                .setPlatform(servicePlanItem.getPlatform())
                .setSupplierId(partnerId)
                .setProductUomId(servicePlanItem.getUom().getId())
                .setCooperationType(servicePlan.getCooperationType())
                .setUsableQty(0.0D).build().execConditionStrategy();
        resultJson = xs51.getResultJson();
        if (resultJson.containsKey("P001")&&resultJson.getDoubleValue("P001")>0){
            double p101 = resultJson.getDoubleValue("P101")/100;
            double p904 = resultJson.getDoubleValue("P904");
            if (p101==0){
                JSONObject t11 = new ConditionBuilder.Builder("T11")
                        .setBrandId(product.getBrand().getId())
                        .setClassifyId(product.getClassify().getId())
                        .setSupplierId(partner.getId()).build().execCondition().getResultJson();
                if (t11.getBigDecimal("P101")!=null)p101 = t11.getBigDecimal("P101").doubleValue()/100 ;
                p904 = resultJson.getDoubleValue("P001")*(1+p101);
            }
            return platformPriceCosInTaxReturnTemp(resultJson.get("P001"),p904,p101,0,0,0,0);
        }
        return new HashMap();
    }

    /**
     * 返回前端的类型
     * @param platformPriceCosExTax
     * @param platformPriceCosInTaxTemp
     * @param taxRate
     * @param materialsCost
     * @param workFee
     * @param siteFee
     * @param platFee
     * @return
     */
    private Map platformPriceCosInTaxReturnTemp(Object platformPriceCosExTax,Object platformPriceCosInTaxTemp,Object taxRate,
                                                Object materialsCost,Object workFee,Object siteFee,Object platFee){
        double tax = 0;
        if (taxRate!=null){
            if (taxRate instanceof BigDecimal){
                tax = ((BigDecimal) taxRate).doubleValue();
            }else if (taxRate instanceof Double){
                tax = (double) taxRate;
            }
        }
        return MapUtil.mapper(
                "platformPriceCosExTax", platformPriceCosExTax==null?0:platformPriceCosExTax,
                "platformPriceCosInTaxTemp", platformPriceCosInTaxTemp==null?0:platformPriceCosInTaxTemp,
                "taxRate", tax/100,
                "materialsCost", materialsCost==null?0:materialsCost,
                "workFee", workFee==null?0:workFee,
                "siteFee", siteFee==null?0:siteFee,
                "platFee", platFee==null?0:platFee
        );
    }
    /**
     * 根据类型找合同
     * @param maintenanceOrder
     * @param planMap
     * @param supplier_id
     * @return
     */
    private boolean getContract(MaintenanceOrder maintenanceOrder, Map planMap, String supplier_id) {
        List<Map> condition = new ArrayList<>();
        condition.add(MapUtil.mapper("field","partner.id","value",supplier_id));
        Page<Map> contractMap = this.invoke("scm.contract.findAllBySupplierOrCooperation",
                MapUtil.mapper("condition",condition,"conditionModel",planMap,"page",0,"size",50));
        Map map = contractMap.getContent().stream().findFirst().orElse(null);
        if (map==null) return true;
        Contract contract = Tools.map(map, Contract.class);
        maintenanceOrder.setContract(contract);
        return false;
    }


    /**
     * 查询空间策略价格
     * @param order
     * @return
     */
    private JSONObject querySpacePlanPrice(MaintenanceOrder order){
        ConditionBuilder cx_kjjh = new ConditionBuilder.Builder("CX_KJJH")
                .setSupplierId(order.getSupplier())
                .setDept(order.getBelongDept())
                .product(order.getProduct())
                .build()
                .execConditionStrategy()
                .formatAmount();
        return cx_kjjh.getResultJson();
    }
}
